home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / ISSUE04 / TYPECAST / BASMU.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-07-20  |  4.4 KB  |  130 lines

  1. unit Basmu;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, ExtCtrls, StdCtrls;
  8.  
  9. type
  10.   TBIOSCounterForm = class(TForm)
  11.     Label1: TLabel;
  12.     Label2: TLabel;
  13.     procedure FormActivate(Sender: TObject);
  14.   private
  15.     { Stores a copy of the BIOS timer counter }
  16.     FBIOSCounter: Longint;
  17.     { Updates FBIOSCounter }
  18.     function GetBIOSCounter: Longint;
  19.   public
  20.     { Simple property to set up and return FBIOSCounter }
  21.     property BIOSCounter: Longint read GetBIOSCounter;
  22.   end;
  23.  
  24. var
  25.   BIOSCounterForm: TBIOSCounterForm;
  26.  
  27. implementation
  28.  
  29. {$R *.DFM}
  30.  
  31. const
  32.   { You really shouldn't do this - i.e. use a hard-coded segment number }
  33.   { in Windows as segments don't exist, only selectors which you need to }
  34.   { obtain via Windows or DPMI calls. However, in Windows 3.x, selector }
  35.   { $40 is coded to be a match for segment $40, the BIOS Data Area }
  36.   BIOSArea = $40;
  37.   BIOSCounterLo = $6C;
  38.   BIOSCounterHi = $6E;
  39.  
  40. {$define VERSION1}
  41.  
  42. {$ifdef VERSION1}
  43. function TBIOSCounterForm.GetBIOSCounter: Longint;
  44. begin
  45.   FBIOSCounter := MemL[BIOSArea:BIOSCounterLo];
  46.   Result := FBIOSCounter;
  47. end;
  48. {$endif}
  49.  
  50. {$ifdef VERSION2}
  51. function TBIOSCounterForm.GetBIOSCounter: Longint;
  52. begin
  53.   LongRec(FBIOSCounter).Lo := MemW[BIOSArea:BIOSCounterLo];
  54.   LongRec(FBIOSCounter).Hi := MemW[BIOSArea:BIOSCounterHi];
  55.   Result := FBIOSCounter;
  56. end;
  57. {$endif}
  58.  
  59. {$ifdef VERSION3}
  60. function TBIOSCounterForm.GetBIOSCounter: Longint;
  61. begin
  62.   WordRec(LongRec(FBIOSCounter).Lo).Lo := Mem[BIOSArea:BIOSCounterLo];
  63.   WordRec(LongRec(FBIOSCounter).Lo).Hi := Mem[BIOSArea:Succ(BIOSCounterLo)];
  64.   WordRec(LongRec(FBIOSCounter).Hi).Lo := Mem[BIOSArea:BIOSCounterHi];
  65.   WordRec(LongRec(FBIOSCounter).Hi).Hi := Mem[BIOSArea:Succ(BIOSCounterHi)];
  66.   Result := FBIOSCounter;
  67. end;
  68. {$endif}
  69.  
  70. {$ifdef VERSION4}
  71. function TBIOSCounterForm.GetBIOSCounter: Longint; assembler;
  72. asm
  73.   mov ax, BIOSArea
  74.   mov es, ax
  75.   mov di, BIOSCounterLo
  76. { Longint's are returned in DX:AX }
  77. { AX is the low result word }
  78.   mov ax, es:[di]
  79.   mov di, BIOSCounterHi
  80. { DX is the high result word }
  81.   mov dx, es:[di]
  82.   les di, Self
  83. { Having loaded the reference to this form in ES:DI, we need to access }
  84. { its FBIOSCounter field. We then need to store AX in its low word. }
  85. { After that we get the high BIOS timer counter word and do the same thing }
  86. { but store AX in the high word. An example of a statement that does this is: }
  87. {       mov TBIOSCounterForm(es:[di]).FBIOSCounter.Word[0], ax }
  88. { We can consider this split into two parts. The part that references the }
  89. { field of interest, i.e. structured variable access, and the part that }
  90. { accesses the relevant word of the field, i.e. unstructured variable }
  91. { access. The structured variable access can be written in these ways: }
  92. {       TBIOSCounterForm(es:[di]).FBIOSCounter       }
  93. {       TBIOSCounterForm[es:di].FBIOSCounter         }
  94. {       TBIOSCounterForm([es:di]).FBIOSCounter       }
  95. {       (TBIOSCounterForm ptr es:[di]).FBIOSCounter  }
  96. {       (TBIOSCounterForm ptr [es:di]).FBIOSCounter  }
  97. {       ([TBIOSCounterForm ptr es:di]).FBIOSCounter  }
  98. {       es:TBIOSCounterForm[di].FBIOSCounter         }
  99. {       es:TBIOSCounterForm([di]).FBIOSCounter       }
  100. {       es:[di].TBIOSCounterForm.FBIOSCounter        }
  101. {       [es:di].TBIOSCounterForm.FBIOSCounter        }
  102. { The unstructured variable access can be written in many different ways: }
  103. { (the *'d formats are valid if you are accessing only the first bytes) }
  104. {       LongRec(structured_part).Lo            }
  105. {    *  Word(structured_part)                  }
  106. {    *  structured_part.Word                   }
  107. {       structured_part.Word.0                 }
  108. {       structured_part.Word[0]                }
  109. {    *  word ptr structured_part               }
  110. {    *  word ptr [structured_part]             }
  111. {       word ptr structured_part + 0           }
  112. {       word ptr [structured_part] + 0         }
  113. {       word ptr [structured_part + 0]         }
  114. { So, to get to the low and high word of this field }
  115. { the following two lines are valid possibilities }
  116.   mov word ptr [(TBIOSCounterForm ptr es:[di]).FBIOSCounter] + 0, ax
  117.   mov es:[di].TBIOSCounterForm.FBIOSCounter.Word.2, dx
  118. end;
  119. {$endif}
  120.  
  121. procedure TBIOSCounterForm.FormActivate(Sender: TObject);
  122. begin
  123.   repeat
  124.     Application.ProcessMessages;
  125.     Label1.Caption := IntToStr(BIOSCounter);
  126.   until Application.Terminated;
  127. end;
  128.  
  129. end.
  130.